package tech.yqyl.store;

import cn.hutool.core.text.StrFormatter;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Splitter;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import tech.yqyl.StringUtil;
import tech.yqyl.YamlUtils;
import tech.yqyl.git.GitRepository;
import tech.yqyl.halo.ArticleEntity;
import tech.yqyl.halo.ArticleStore;
import tech.yqyl.halo.HaloMarkdownBoot;
import tech.yqyl.solo.Article;
import tech.yqyl.solo.BlogInfo;
import tech.yqyl.solo.BlogProcessor;
import tech.yqyl.solo.processor.AggregationProcessor;
import tech.yqyl.solo.processor.LocalPath2WebSiteProcessor;
import tech.yqyl.solo.processor.MetaConfig;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @className: FileConfig
 * @description:
 * @author: caoyangjie
 * @date: 2024/9/3
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class File2HaloArticleStore {
    ArticleStore articleStore = new ArticleStore();
    BlogProcessor targetProcessor;
    BlogProcessor readmeProcessor = new LocalPath2WebSiteProcessor();
    private String basePath;
    private String tag;
    private String readmePath;
    private String initPath;
    private boolean seriesFlag;
    private String categories;

    public File2HaloArticleStore(String basePath, String categories, MetaConfig config) {
        this.targetProcessor = new AggregationProcessor(config);
        this.basePath = basePath;
        this.categories = StringUtil.isEmpty(categories)?"默认分类":categories;
        Path bPath = Paths.get(basePath);
        if( bPath.toFile().exists() && bPath.toFile().isDirectory() ) {
            this.readmePath = basePath.concat(File.separator).concat("README.md");
            this.tag = bPath.toFile().getName();
            this.seriesFlag = true;
        } else {
            this.seriesFlag = false;
            this.tag = "待分类";
            this.initPath = basePath.replace(".md",".json");
        }
//        if( seriesFlag && !Paths.get(this.readmePath).toFile().exists() ) {
//            throw new RuntimeException("当前操作未能找到 : README.md 请检查!");
//        }
    }

    public void store() {
        String[] tagName = new String[1];
        tryGetBlog().stream().forEach(blog->{
            // 处理 blog
            targetProcessor.process(blog);
            ArticleEntity ae = new ArticleEntity();
            ae.setTitle(blog.getArticle().getArticleTitle());
            ae.setSlugId(blog.getArticle().getOId());
            ae.setMetadataName(UUID.randomUUID().toString());
            ae.setTags(blog.getArticle().getArticleTags());
            tagName[0] = blog.getArticle().getFirstTag();
            ae.setCategories(blog.getCategories());
            ae.setRawContent(blog.getCtxList().stream().map(ctx->ctx.getMarkdownContent()).collect(Collectors.joining("\n")));
            ae.setContent( blog.getCtxList().stream().map(ctx->ctx.getHtmlContent()).collect(Collectors.joining("\n")) );
            if( !blog.isReadmeFlag() && YamlUtils.getConfig().getLocalStore().isCache() ) {
                String markdownFile = blog.getBlogFile().getAbsolutePath();
                markdownFile = markdownFile.replace(".md","_CopyRight.md");
                try {
                    Files.write(Paths.get(markdownFile), ae.getRawContent().getBytes(StandardCharsets.UTF_8));
                } catch (IOException e) {
                    System.err.println(StrFormatter.format("写入处理后的源markdown文件: [{}]失败!原因为： {}", markdownFile, e.getMessage()));
                }
            }
            articleStore.createOrUpdate(ae);
        });
        GitRepository repo = GitRepository.init();
        repo.commit(tagName[0], StrFormatter.format("推送博客文章系列: {},提交图片资源!", tagName[0]));
        repo.push();
    }

    protected List<BlogInfo> tryGetBlog() {
        if( !seriesFlag ) {
            BlogInfo info = getOne();
            if( info==null ) {
                return new ArrayList<>();
            }
            return Arrays.asList(getOne());
        } else {
            return listAll();
        }
    }

    private BlogInfo getOne() {
        try {
            File blogFile = Paths.get(basePath).toFile();
            JSONObject jsonConfig;
            if( Paths.get(initPath).toFile().exists() ) {
                String initJson = new String(Files.readAllBytes(Paths.get(initPath)), Charset.forName("UTF-8"));
                jsonConfig = JSONObject.parseObject(initJson);
            } else {
                jsonConfig = new JSONObject();
                jsonConfig.put("tags","待分类");
            }
            String content = Files.readAllLines(blogFile.toPath(), Charset.forName("UTF-8")).stream().collect(Collectors.joining("\n"));
            Article art = new Article();
            // 防止出现 hash后截取前 16位一样的情况
            art.setOId(StringUtil.hashString(blogFile.getName().concat(jsonConfig.getString("tags"))));
            art.setArticleTitle(blogFile.getName());
            art.setArticleTags(jsonConfig.getString("tags"));
            art.setArticleContent(content);
            return new BlogInfo(categories, art, blogFile);
        } catch (IOException e) {
        }
        System.err.println(StrFormatter.format("处理文件[{}]转换为BlogInfo失败!", basePath));
        return null;
    }

    private List<BlogInfo> listAll() {
        List<BlogInfo> blogs = new ArrayList<>();
        Map<String, String> oidTitleMaps = new HashMap<>();
        Path readme = Paths.get(basePath.concat(File.separator).concat("README.md"));
        if( readme.toFile().isFile() ) {
            blogs.add(doWithReadMeFile(readme.toFile(), oidTitleMaps));
        }
        oidTitleMaps.keySet().stream().sorted().forEach(oid->{
            File blogFile = Paths.get(basePath.concat(File.separator).concat(oid.startsWith(".")?oid.substring(1):oid)).toFile();
            BlogInfo info = doWithBlogFile(blogFile, oidTitleMaps);
            if( info!=null ) {
                blogs.add( info );
            } else {
                System.err.println(StrFormatter.format("处理文件[{}]转换为BlogInfo失败!", blogFile.getAbsolutePath()));
            }
        });
        return blogs;
    }

    private BlogInfo doWithBlogFile(File blogFile, Map<String, String> oidTitleMaps) {
        if( blogFile.isFile() ) {
            try {
                String tag = Paths.get(basePath).toFile().getName();
                List<String> blogContentLines = Files.readAllLines(blogFile.toPath(),Charset.forName("UTF-8"));
                String content = blogContentLines.stream().collect(Collectors.joining("\n"));
                Article art = new Article();
                // 获取文件名 去除 .md 即为 oid
                String fileName = blogFile.getName();
                String affix = StringUtil.containsChinese(fileName)?StringUtil.hashString(fileName):fileName;
                art.setOId(affix.replace(".md",""));
                String title = StringUtil.isEmpty(oidTitleMaps.get("./".concat(blogFile.getName())))?blogContentLines.get(0):oidTitleMaps.get("./".concat(blogFile.getName()));
                art.setArticleTitle(title);
                art.setArticleTags(tag);
                art.setArticleContent(content);
                return new BlogInfo(categories, art, blogFile);
            } catch (IOException e) {
            }
        }
        return null;
    }

    private BlogInfo doWithReadMeFile(File readmeFile, Map<String, String> oidTitleMaps) {
        try {
            List<String> readmeLines = Files.readAllLines(readmeFile.toPath(),Charset.forName("UTF-8"));
            List<String> linkReadmeLines = new ArrayList<String>();
            if( !(readmeLines.get(0).contains("#") && readmeLines.get(0).contains(tag)) ) {
                linkReadmeLines.add(StrFormatter.format("# {}", tag));
            }
            for(String line : readmeLines) {
                if( line.contains("[") && line.contains(")") ) {
                    List<String> oids = StringUtil.find("oid", line);
                    List<String> titles = StringUtil.find("title", line);
                    for( int i=0; i < oids.size(); i++ ) {
                        String oid = oids.get(i);
                        if( oid.endsWith(".md") || oid.endsWith(".MD") ) {
                            List<String> oidValues = Splitter.on("/").splitToList(oid);
                            // 如果包含中文,则转换
                            String affix = StringUtil.containsChinese(oidValues.get(oidValues.size()-1))?StringUtil.hashString(oidValues.get(oidValues.size()-1)):oidValues.get(oidValues.size()-1).replace(".md","").replace(".MD","");
                            String linkMd = StrFormatter.format("{}/archives/{}", HaloMarkdownBoot.server.getDomain(), affix);
                            line = line.replaceAll(oid, linkMd);
                            oidTitleMaps.put(oid, titles.get(i));
                        }
                    }
                }
                linkReadmeLines.add(line);
            }
            Article art = new Article();
            // 获取文件名 去除 .md 即为 oid
            art.setArticleTitle(tag.contains("系列")?tag:tag.concat("系列文章"));
            art.setOId(StringUtil.hashString(art.getArticleTitle()));
            art.setArticleTags(tag.concat(",link分类"));
            art.setArticleContent( linkReadmeLines.stream().collect(Collectors.joining("\n")) );
            return new BlogInfo(categories, art, readmeFile).setReadMeFlag();
        } catch (IOException e) {
        }
        return null;
    }

    public static void main(String[] args) {
//        File2HaloArticleStore store = new File2HaloArticleStore("/newcloud/blog-document/blog/精通高并发系列","技术板块",MetaConfig.toHaloNoRightConfig());
//        FileArticleStore store = new FileArticleStore("/newcloud/blog-document/blog/语法学习");
//        FileArticleStore store = new FileArticleStore( "/newcloud/blog-document/blog/linux网络传输", "");
//        FileArticleStore store = new FileArticleStore( "/newcloud/blog-document/blog/netty系列学习", "技术板块", MetaConfig.toHaloNoRightConfig());
//        YamlUtils.getConfig().getLocalStore().setTitleHead(true);
        // 如果 markdown 中存在图片，并且markdown的内容是 github上获取的, 则需要设置 githubUri 来下载图片
//        YamlUtils.getConfig().getImgBed().setGithubUri("https://raw.githubusercontent.com/qier222/YesPlayMusic/master/");
        String parentDir = "/newcloud/blog-document/blog/个人知识版权/黑科技软件推荐";
        StringUtil.generateReadme(parentDir);
        File2HaloArticleStore store = new File2HaloArticleStore(parentDir,"技术板块",MetaConfig.getFromConfig());
        store.store();
    }
}
